<!DOCTYPE html>



  


<html class="theme-next muse use-motion" lang="en">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-32x32.ico?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="UNIX,C," />





  <link rel="alternate" href="/atom.xml" title="JOE'S BLOG" type="application/atom+xml" />






<meta name="description" content="引言UNIX系统提供的经典进程间通信机制(IPC): 管道、FIFO、消息队列、信号量以及共享存储。这些机制允许在同一台计算机上运行的进程可以相互通信。本章内容主要是研究在不同计算机上的进程相互通信的机制: 网络进程间通信(network IPC)。">
<meta name="keywords" content="UNIX,C">
<meta property="og:type" content="article">
<meta property="og:title" content="网络IPC: 套接字(十六)">
<meta property="og:url" content="https://joewt.com/2018/08/03/network-IPC/index.html">
<meta property="og:site_name" content="JOE&#39;S BLOG">
<meta property="og:description" content="引言UNIX系统提供的经典进程间通信机制(IPC): 管道、FIFO、消息队列、信号量以及共享存储。这些机制允许在同一台计算机上运行的进程可以相互通信。本章内容主要是研究在不同计算机上的进程相互通信的机制: 网络进程间通信(network IPC)。">
<meta property="og:locale" content="en">
<meta property="og:updated_time" content="2018-08-03T08:50:12.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="网络IPC: 套接字(十六)">
<meta name="twitter:description" content="引言UNIX系统提供的经典进程间通信机制(IPC): 管道、FIFO、消息队列、信号量以及共享存储。这些机制允许在同一台计算机上运行的进程可以相互通信。本章内容主要是研究在不同计算机上的进程相互通信的机制: 网络进程间通信(network IPC)。">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Muse',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":true,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Author'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://joewt.com/2018/08/03/network-IPC/"/>





  <title>网络IPC: 套接字(十六) | JOE'S BLOG</title>
  








</head>



<body itemscope itemtype="http://schema.org/WebPage" lang="en">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">JOE'S BLOG</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">好记性不如烂键盘</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            About
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            Tags
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            Categories
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            Archives
          </a>
        </li>
      
        
        <li class="menu-item menu-item-book">
          <a href="/book/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-book"></i> <br />
            
            book
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://joewt.com/2018/08/03/network-IPC/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="JOE">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/assets/img/favicon1.png">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JOE'S BLOG">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">网络IPC: 套接字(十六)</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2018-08-03T14:03:47+08:00">
                2018-08-03
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">In</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/UNIX环境高级编程/" itemprop="url" rel="index">
                    <span itemprop="name">UNIX环境高级编程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
              <span class="post-comments-count">
                <span class="post-meta-divider">|</span>
                <span class="post-meta-item-icon">
                  <i class="fa fa-comment-o"></i>
                </span>
                <a href="/2018/08/03/network-IPC/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count gitment-comments-count" data-xid="/2018/08/03/network-IPC/" itemprop="commentsCount"></span>
                </a>
              </span>
            
          

          
          

          
            <span class="post-meta-divider">|</span>
            <span class="page-pv"><i class="fa fa-file-o"></i>
            <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>
            </span>
          

          
            <div class="post-wordcount">
              
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">Words count in article&#58;</span>
                
                <span title="Words count in article">
                  
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">Reading time &asymp;</span>
                
                <span title="Reading time">
                  
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>UNIX系统提供的经典进程间通信机制(IPC): 管道、FIFO、消息队列、信号量以及共享存储。这些机制允许在同一台计算机上运行的进程可以相互通信。本章内容主要是研究在不同计算机上的进程相互通信的机制: 网络进程间通信(network IPC)。  </p>
<a id="more"></a>
<h2 id="套接字描述符"><a href="#套接字描述符" class="headerlink" title="套接字描述符"></a>套接字描述符</h2><p>套接字描述符在UNIX系统上被当做一种文件描述符，UNIX系统一切皆文件。<br>调用socket函数，创建一个套接字  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int socket(int damain, int type, int protocol);</span><br><span class="line">//成功：返回描述符，出错：返回-1</span><br></pre></td></tr></table></figure>
<p>参数domain确定通信特征，包括地址格式  </p>
<table>
<thead>
<tr>
<th style="text-align:left">域</th>
<th style="text-align:left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">AF_INET</td>
<td style="text-align:left">IPv4</td>
</tr>
<tr>
<td style="text-align:left">AF_INET6</td>
<td style="text-align:left">IPv6</td>
</tr>
<tr>
<td style="text-align:left">AF_UNIX</td>
<td style="text-align:left">UNIX域</td>
</tr>
<tr>
<td style="text-align:left">AF_UPSPEC</td>
<td style="text-align:left">未指定</td>
</tr>
</tbody>
</table>
<p>参数type确定套接字类型，进一步确定通信特征   </p>
<table>
<thead>
<tr>
<th style="text-align:left">类型</th>
<th style="text-align:left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">SOCK_DGRAM</td>
<td style="text-align:left">固定长度、无连接、不可靠的报文传递</td>
</tr>
<tr>
<td style="text-align:left">SOCK_RAW</td>
<td style="text-align:left">IP协议的数据报接口</td>
</tr>
<tr>
<td style="text-align:left">SOCK_SEQPACKET</td>
<td style="text-align:left">固定长度、有序的、可靠的、面向连接的报文传递</td>
</tr>
<tr>
<td style="text-align:left">SOCK_STREAM</td>
<td style="text-align:left">有序的、可靠的、双向的、面向连接的字节流</td>
</tr>
</tbody>
</table>
<p>参数protocal通常是0、表示为给定的域和套接字类型选择默认协议  </p>
<p>数据报(SOCK_DGRAM)接口，类似于UDP通信，两个对等进程之间通信时不需要逻辑连接。只需要向对等进程所使用的套接字送出一个报文。<br>字节流(SOCK_STREAM),类似于TCP，在交换数据前，需要建立一个逻辑连接。  </p>
<p>套接字通信时双向的。可以采用shutdown函数来禁止一个套接字的I/O。  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int shutdown(int sockfd, int how);</span><br><span class="line">//成功：返回0 失败：返回-1</span><br></pre></td></tr></table></figure>
<p>how参数  </p>
<ul>
<li>SHUT_RE(关闭读端)，无法从套接字读取数据</li>
<li>SHUT_WR(关闭写端)，无法使用套接字发送数据</li>
<li>SHUT_RDWR，无法读，也无法读  </li>
</ul>
<p>有两个函数用于点分十进制和二进制地址格式之前的相互转换  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;arpa/inet.h&gt;</span><br><span class="line">const char *inet_ntop(int domain, const void *restrict addr,</span><br><span class="line">                    char *restrict str, socklen_t size);</span><br><span class="line">                    //成功：返回地址字符串指针，出错：返回NULL</span><br><span class="line"></span><br><span class="line">int inet_pton(int domain, const char *restrict str,</span><br><span class="line">                void *restrict addr);</span><br><span class="line">                    //成功：返回1，格式无效返回0，失败：返回-1</span><br></pre></td></tr></table></figure>
<h2 id="将套接字与地址关联"><a href="#将套接字与地址关联" class="headerlink" title="将套接字与地址关联"></a>将套接字与地址关联</h2><p>使用bind函数来关联地址和套接字  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int bind(int sockfd, const struct sockaddr *addr, socklen_t len);</span><br><span class="line">//成功：返回0，失败：返回-1</span><br></pre></td></tr></table></figure>
<h2 id="建立连接"><a href="#建立连接" class="headerlink" title="建立连接"></a>建立连接</h2><p>使用connect函数来建立连接  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int connect(int sockfd, const struct sockaddr *addr, socklen_t len);</span><br><span class="line">//成功：返回0，失败：返回-1</span><br></pre></td></tr></table></figure>
<p>在connect中指定的地址是我们想与之通信的服务器地址。如果sockfd没有绑定到一个地址，connect会给调用者绑定一个默认地址。  </p>
<p>服务器调用listen函数宣告它愿意接受连接请求  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int listen(int sockfd, int backlog);</span><br><span class="line">//成功：返回0，失败：返回-1</span><br></pre></td></tr></table></figure>
<p>参数backlog提供了一个提示，提示系统该进程所要入队的未完成连接请求数量。实际值由系统决定<br>一旦队列满，系统就会拒绝多余的连接请求，所以backlog的值应该基于服务器期望负载和处理量来选择，其中处理量是指接受连接请求与启动服务的数量。<br>一旦服务器调用了listen，所用的套接字就能接收连接请求。使用accept函数来获得连接请求并建立连接。  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">int accept(int sockfd, struct sockaddr *restrict addr,</span><br><span class="line">            socklen_t *restrict len);</span><br><span class="line">            //成功：返回文件描述符，出错：返回-1</span><br></pre></td></tr></table></figure>
<p>函数accept返回的是套接字描述符，该描述符连接到调用connect的客户端。这个新的套接字描述符和原始套接字(sockfd)具有相同的套接字类型和地址族。传给accept的原始套接字没有关联到这个连接，而是继续保持可用状态并接收其他连接请求。<br>如果不关心客户端标识，可以将参赛addr和len设为NULL。否则，在调用accept之前，将addr参数设为足够大的缓冲区来存放地址，并且将len指向的整数设为这个缓冲区的字节大小。返回时，accept会在缓冲区填充客户端的地址，并且更新指向len的整数来反映该地址的大小。<br>如果没有连接请求等待，accept会阻塞直到一个请求到来。如果sockfd处于非阻塞模式，accept会返回-1，并将errno设置为EAGAIN或EWOULDBLOCK。<br>如果服务器调用accept，并且当前没有连接请求，服务器会阻塞直到一个请求到来。另外，服务器可以使用poll或select来等待一个请求的到来。在这种情况下，一个带有等待连接请求的套接字会以可读的方式出现。  </p>
<h2 id="数据传输"><a href="#数据传输" class="headerlink" title="数据传输"></a>数据传输</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);</span><br><span class="line">//成功: 返回发送的字节数，失败：返回-1</span><br></pre></td></tr></table></figure>
<p>对于支持报文边界的协议，如果尝试发送单个报文的长度超过协议锁支持的最大长度，那么send会失败，并将errno设为EMSGSIZE。对于字节流协议，send会阻塞直到整个数据传输完成。函数sendto和send类似。区别在于sendto可以在无连接的套接字上指定一个目标地址。  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flags, const struct sockaddr * destaddr, socklen_t destlen);</span><br><span class="line">//成功：返回发送的字节数，失败：返回-1</span><br></pre></td></tr></table></figure>
<p>使用recv函数接收数据   </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;sys/socket.h&gt;</span><br><span class="line">ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);</span><br><span class="line">//返回数据的字节长度，无数据或等放已经按序结束，返回0，出错：返回-1</span><br></pre></td></tr></table></figure>
<h2 id="非阻塞和异步I-O"><a href="#非阻塞和异步I-O" class="headerlink" title="非阻塞和异步I/O"></a>非阻塞和异步I/O</h2><p>通常，recv函数没有数据可用时会阻塞等待。同样的，当套接字输出队列没有足够空间来发送消息时，send函数会阻塞。在套接字非阻塞模式下，行为会改变。在这种情况下，这些函数不会阻塞而是会失败，将errno设置为EWOULDBLOCK或者EAGAIN。当这种情况发生时，可以用poll或select来判断能否接收或者传输数据。  </p>
<p>Single UNIX Specification 包含通用异步I/O机制的支持。套接字机制有自己的处理异步I/O的方式。<br>在基于套接字的异步I/O中，当从套接字中读取数据时，或者当套接字写队列中空间变得可用时，可以安排要发送的信号SIGIO。<br>启用异步I/O的步骤  </p>
<ol>
<li>建立套接字所有权，这样信号可以被传递到合适的进程。  <ul>
<li>在fcntl中使用F_SETOWN命令</li>
<li>在ioctl中使用FIOSETOWN命令</li>
<li>在ioctl中使用SIOCSGRP命令 </li>
</ul>
</li>
<li>通知套接字当I/O操作不会阻塞时发信号。  <ul>
<li>在fcntl中使用F_SETFL命令并且启用文件标志<code>O_ASYNC</code>。</li>
<li>在ioctl中使用FIOASYNC命令。</li>
</ul>
</li>
</ol>
<p>但没有得到普遍支持</p>

      
    </div>
    
    
    

    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div>感谢土豪</div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>Donate</span>
  </button>
  <div id="QR" style="display: none;">

    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="/assets/img/alipay.png" alt="JOE Alipay"/>
        <p>Alipay</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    
      <div>
        <ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>Post author:</strong>
    JOE
  </li>
  <li class="post-copyright-link">
    <strong>Post link:</strong>
    <a href="https://joewt.com/2018/08/03/network-IPC/" title="网络IPC: 套接字(十六)">https://joewt.com/2018/08/03/network-IPC/</a>
  </li>
  <li class="post-copyright-license">
    <strong>Copyright Notice: </strong>
    All articles in this blog are licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/" rel="external nofollow" target="_blank">CC BY-NC-SA 3.0</a> unless stating additionally.
  </li>
</ul>

      </div>
    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/UNIX/" rel="tag"># UNIX</a>
          
            <a href="/tags/C/" rel="tag"># C</a>
          
        </div>
      

      
      
        <div class="post-widgets">
        

        

        
          
          <div id="needsharebutton-postbottom">
            <span class="btn">
              <i class="fa fa-share-alt" aria-hidden="true"></i>
            </span>
          </div>
        
        </div>
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2018/07/10/daemons/" rel="next" title="守护进程(十三)">
                <i class="fa fa-chevron-left"></i> 守护进程(十三)
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/08/27/mysql-optimize-1/" rel="prev" title="记一次性能优化点">
                记一次性能优化点 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      
        <div id="gitment-container"></div>
      
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            Table of Contents
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            Overview
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/assets/img/favicon1.png"
                alt="JOE" />
            
              <p class="site-author-name" itemprop="name">JOE</p>
              <p class="site-description motion-element" itemprop="description">爱生活，爱coding</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">22</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">9</span>
                  <span class="site-state-item-name">categories</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">11</span>
                  <span class="site-state-item-name">tags</span>
                </a>
              </div>
            

          </nav>

          
            <div class="feed-link motion-element">
              <a href="/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/yinrenxin" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="mailto:joewttx@163.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
            </div>
          

          
          

          
          
            <div class="links-of-blogroll motion-element links-of-blogroll-block">
              <div class="links-of-blogroll-title">
                <i class="fa  fa-fw fa-link"></i>
                Links
              </div>
              <ul class="links-of-blogroll-list">
                
                  <li class="links-of-blogroll-item">
                    <a href="http://learnerwn.github.io" title="Murphy" target="_blank">Murphy</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://strcpy.me" title="virusdefender" target="_blank">virusdefender</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://qulongjun.com/" title="落苏" target="_blank">落苏</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://tysb7.cn/" title="汤圆" target="_blank">汤圆</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://aconion.com" title="阿葱" target="_blank">阿葱</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://csy-anxuanxun.cn" title="csy" target="_blank">csy</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://hakana.cn" title="幻梦" target="_blank">幻梦</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://blog.fastrun.cn" title="CrazyCodes" target="_blank">CrazyCodes</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="http://www.heanny.cn" title="Heanny" target="_blank">Heanny</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://vkkevin.xyz" title="Kevin" target="_blank">Kevin</a>
                  </li>
                
              </ul>
            </div>
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#引言"><span class="nav-number">1.</span> <span class="nav-text">引言</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#套接字描述符"><span class="nav-number">2.</span> <span class="nav-text">套接字描述符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#将套接字与地址关联"><span class="nav-number">3.</span> <span class="nav-text">将套接字与地址关联</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#建立连接"><span class="nav-number">4.</span> <span class="nav-text">建立连接</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#数据传输"><span class="nav-number">5.</span> <span class="nav-text">数据传输</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#非阻塞和异步I-O"><span class="nav-number">6.</span> <span class="nav-text">非阻塞和异步I/O</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">JOE</span>

  
</div>


  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a></div>








        
<div class="busuanzi-count">
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

  
    <span class="site-uv">
      <i class="fa fa-user"></i>
      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
      
    </span>
  

  
    <span class="site-pv">
      <i class="fa fa-eye"></i>
      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
      
    </span>
  
</div>








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
          <span id="scrollpercent"><span>0</span>%</span>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  








  







<!-- LOCAL: You can save these files to your site and update links -->
    
        
        <link rel="stylesheet" href="https://billts.site/extra_css/gitment.css">
        <script src="https://billts.site/js/gitment.js"></script>
    
<!-- END LOCAL -->

    

    
      <script type="text/javascript">
      function renderGitment(){
        var gitment = new Gitmint({
            id: window.location.pathname, 
            owner: 'Joewt',
            repo: 'blogComment',
            
            lang: "" || navigator.language || navigator.systemLanguage || navigator.userLanguage,
            
            oauth: {
            
            
                client_secret: 'aeba4f8f14a7d3464ef3ea9faef0d67409229e47',
            
                client_id: '12908903defa4c3347b8'
            }});
        gitment.render('gitment-container');
      }

      
      renderGitment();
      
      </script>
    







  





  

  

  
<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>


  
  
  
  <link rel="stylesheet" href="/lib/needsharebutton/needsharebutton.css">

  
  
  <script src="/lib/needsharebutton/needsharebutton.js"></script>

  <script>
    
      pbOptions = {};
      
          pbOptions.iconStyle = "box";
      
          pbOptions.boxForm = "horizontal";
      
          pbOptions.position = "bottomCenter";
      
          pbOptions.networks = "Weibo,Wechat,Douban,QQZone,Twitter,Facebook";
      
      new needShareButton('#needsharebutton-postbottom', pbOptions);
    
    
  </script>

  

  

  

  

<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":75,"height":150},"mobile":{"show":true},"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/"});</script></body>
</html>
